package com.qf.controller;

import com.qf.service.GoodService;
import com.qf.service.OrderService;
import com.qf.service.ProductService;
import com.qf.service.UserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;

/**
 * 首页统计, 仪表盘
 */
@RestController
@CrossOrigin("*")
@RequestMapping("/dashboard")
public class IndexController {
    @Autowired
    private UserService userService;
    @Autowired
    private GoodService goodService;
    @Autowired
    private ProductService productService;

    @Autowired
    private OrderService orderService;


    /**
     * 首页统计数据
     * * 用户量, 商品量, 货品量, 订单量
     * * {
     * *         "goodsTotal":426, 商品量
     * *         "userTotal":197, 用户量
     * *         "productTotal":8939, 货品量
     * *         "orderTotal":107 订单量
     * *     }
     *
     * @return
     */
    @GetMapping("")
    public Object index() {
        int userTotal = userService.countUser();
        int goodsTotal = goodService.countGood();
        int productTotal = productService.productCount();
        int orderTotal = orderService.countOrder();

        Map<String, Integer> map = new HashMap<>();
        map.put("userTotal", userTotal);
        map.put("goodsTotal", goodsTotal);
        map.put("productTotal", productTotal);
        map.put("orderTotal", orderTotal);
        return ResponseUtil.ok(map);
    }

    /**
     * 首页数据可视化图表地址 : http://localhost:8083/admin/dashboard/chart
     * -下行数据 :
     * categorySell : 商品分类和对应分类的销售额
     * orderAmts : 日期和对应的订单总额, 订单笔数
     * userOrderCnt : 日期对应的用户数和订单数
     */

    @GetMapping("/chart")
    public Object chart() {
        //1、查询数据库统计日期和用户的增长量
        List<DayStatis> userCnts = userService.userCnts();

        //2、查询数据库统计商品分类和对应分类的销售额
        List<CategorySellAmts> categoryCnts = orderService.categorySellCount();

        //3、查询数据库统计日期和对应的订单总额，订单笔数
        List<DayStatis> orderCnts = orderService.orderAmts();

        //4、封装日期、用户增长量，订单量vo
        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();
        //整合了用户统计集合和订单统计集合中的所有日期
        String[] dayArray = mergeDayData(userCnts, orderCnts);
        //日期
        userOrderCntVo.setDayData(dayArray);
        //订单量
        int[] orderCntArray = fetchCnt(dayArray, orderCnts);
        userOrderCntVo.setOrderCnt(orderCntArray);
        //用户增长量
        int[] userCntArray = fetchCnt(dayArray, userCnts);
        userOrderCntVo.setUserCnt(userCntArray);

        //5、封装日期以及对应的订单金额，订单笔数
        OrderAmtsVo orderAmtsVo = fetchOrderAmts(orderCnts);
        //6、封装商品分类和对应分类的销售额
        CategorySellVo categorySellVo = fetchCategorySll(categoryCnts);
        //7、将vo封装到hashMap
        Map<String,Object> map = new HashMap<>();
        map.put("userOrderCnt",userOrderCntVo);
        map.put("orderAmts",orderAmtsVo);
        map.put("categorySell",categorySellVo);
        return ResponseUtil.ok(map);
    }

    /**
     * 合并去重用户统计结果日期和订单统计结果日期
     *
     * @param userCnts  统计日期和用户的增长量数据
     * @param orderCnts 统计日期和对应的订单总额，订单笔数数据
     * @return
     */
    private String[] mergeDayData(List<DayStatis> userCnts, List<DayStatis> orderCnts) {
        //1、设置set集合，用于过滤重复的日期
        Set<String> daySet = new HashSet<>();
        //2、遍历用户和日期的数据集合
        for (DayStatis userCnt : userCnts) {
            daySet.add(userCnt.getDayStr());
        }
        //3、遍历订单和日期的数据集合
        for (DayStatis orderCnt : orderCnts) {
            daySet.add(orderCnt.getDayStr());
        }
        //4、将set集合中的日期，转换为list,因为set无序，list有序，日期需要排序
        List<String> dayList = new ArrayList<>(daySet);
        //5、对list中的日期进行排序
        Collections.sort(dayList);
        //6、将日期转换成数组返回，数组也是有序的
        return dayList.toArray(new String[0]);
    }

    /**
     * 根据日期获取用户增长量或者订单数量
     *
     * @param dayArray    日期（整合了用户统计结果和订单统计结果的完整日期）
     * @param statisCount 可能是用户增长量统计数据也可能是订单数量统计数据
     * @return
     */
    private int[] fetchCnt(String[] dayArray, List<DayStatis> statisCount) {
        //1、声明数组用来存放统计的量，长度和日期个数相等
        int[] cnts = new int[dayArray.length];
        //2、遍历日期集合
        for (int i = 0; i < dayArray.length; i++) {
            String dayStr = dayArray[i];
            //3、遍历统计的日期和用户量也许是订单集合
            for (DayStatis dayStatis : statisCount) {
                //4、遍历过程中找到对应日期的数据
                if (dayStr.equals(dayStatis.getDayStr())) {
                    cnts[i] = dayStatis.getCnts();
                    break;
                }
            }
        }
        return cnts;
    }

    /**
     * 封装日期订单，订单量，订单金额集合
     *
     * @return
     */
    public OrderAmtsVo fetchOrderAmts(List<DayStatis> orderCnts) {
        //1、创建封装的vo
        OrderAmtsVo vo = new OrderAmtsVo();
        //用来存放集合元素个数的变量
        int size = 0;
        //2、判断如果集合不为空，获取集合大小
        if (orderCnts != null && orderCnts.size() > 0) {
            size = orderCnts.size();
        }
        //3、声明存放日期的集合，存放订单量的集合，存放订单金额的集合
        String[] dayArray = new String[size];
        BigDecimal[] orderAmtData = new BigDecimal[size];
        int[] orderCntData = new int[size];
        //4、遍历集合将对应的元素存储到对应的位置上
        for (int i = 0; i < orderCnts.size(); i++) {
            dayArray[i] = orderCnts.get(i).getDayStr();
            orderAmtData[i] = orderCnts.get(i).getAmts();
            orderCntData[i] = orderCnts.get(i).getCnts();
        }
        //5、将数据存储到vo中
        vo.setDayData(dayArray);
        vo.setOrderAmtData(orderAmtData);
        vo.setOrderCntData(orderCntData);
        return vo;
    }

    /**
     * 封装对应的分类和销售额数据
     * @param categoryCnts
     * @return
     */
    private CategorySellVo fetchCategorySll(List<CategorySellAmts> categoryCnts){
        //1、声明封装的vo对象
        CategorySellVo vo = new CategorySellVo();
        //2、声明用来存储分类名称的数组
        int size = 0;
        if (categoryCnts != null && categoryCnts.size()>0){
            size = categoryCnts.size();
        }
       String[] nameArray = new String[size];
        //3、遍历集合提取分类名字数据
        for (int i = 0; i < categoryCnts.size(); i++) {
            nameArray[i] = categoryCnts.get(i).getName();
        }
        vo.setCategoryNames(nameArray);
        vo.setCategorySellData(categoryCnts);
        return vo;
    }
}
